// import * as schedule from "node-schedule";
import * as fs from "fs";
// import {
//   getStat,
//   createDirectorySync,
//   creatContentToPathSync,
//   formatDate,
//   getCurrentDirPath,
//   isExistPath,
// } from "../utils/fs";
// import { success, fail, ProxyMode } from "../utils/base";
import type { Stats } from "fs";
import axios from "axios";
import lockfile from "proper-lockfile";

let logMax = 2000;
/**
 * @description: teams 通知
 * @param {any} val 请求参数
 */
const sendTeamsMsg = async (val: any) => {
  // 方式一: 必须升级版本才能解决(header)这个问题
  // const options: any = {
  //   responseType: "json",
  //   // headers: {
  //   //   "content-type": "application/json",
  //   //   accept: "application/json",
  //   // },
  //   method: "post",
  //   body: JSON.stringify(val.body),
  // };
  //  return $fetch(val.url, options);

  // 方式二
  axios.post(val.url, val.body);
};

export default defineEventHandler(async (event) => {
  // 获取请求地址：
  // const apiname = getRouterParam(event, "name");
  // 获取请求参数 get
  // const query = getQuery(event)
  // console.log("--请求地址：", apiname);
  // 1. 获取请求参数 post
  const body = await readBody(event);
  // console.log("获取请求参数：", body);
  // 2. 获取当前文件的 Path
  const { writePath, filePath, filePathRoot } = getCurrentDirPath(
    "/public/log",
    "watch-log.json"
  );
  const saveFilePath = filePathRoot || filePath;

  // 2.1 是否存在次目录
  let isHas = false;
  try {
    isHas = await isExistPath(saveFilePath!);
  } catch (error) {
    isHas = false;
  }

  // 3. 检查锁
  if (isHas) {
    const isLocked = await lockfile.check(saveFilePath);
    if (isLocked) return success("文件已经枷锁,无法保存");
  }

  // 4. 获取单例
  const g = ProxyMode();
  // 5. 控制日志上报功能开关
  if (body.isOpenLogReport === false) {
    g.isOpen = false;
    g.asyncNums = 0; // 这里重置一下(有未知情况会导致asyncNums变大,且无法变小),保证能够进行后续操作
    return success({ msg: "关闭-日志上报" });
  } else if (body.isOpenLogReport === true) {
    g.isOpen = true;
    return success({ msg: "开启-日志上报" });
  }
  // 6. 删除日志条数,就算日志没有开启上报也能进行修改删除
  if (!g.isOpen && !body.removeLog)
    return success({ msg: "未开启日志上报功能" });
  // 7. 防止并发过大
  try {
    g.asyncNums++;
    if (g.asyncNums > 3) {
      return success(`服务器繁忙${g.asyncNums}`);
    }
  } catch (error: any) {
    return fail(`服务端并发过大,已拦截${error.message}`);
  }
  /******** start 上报过滤 start ********/
  // 8. 如果是图片加载失败,直接过滤掉,不需要保存(目前平台大部分用户的头像都有问题)
  if (body.data && body.data.name && body.data.name.includes("图片加载失败")) {
    return success("图片加载失败,已过滤");
  }
  if (body.data && body.data.name && body.data.name.includes("link加载失败")) {
    // 过滤已下两种情况数据
    // "message": "资源地址: https://asset.onetrader.online/",
    // "message": "资源地址: ",
    if (
      body.data.message &&
      body.data.message.includes("资源地址") &&
      (body.data.message.length < 10 ||
        body.data.message == "资源地址: https://asset.onetrader.online/")
    ) {
      return success("link加载失败,无具体地址 OR 地址有误,已过滤");
    }
  }
  if (body.data && body.data.message) {
    if (body.data.message.includes("Script error")) {
      return success("Script error,已过滤");
    }
  }
  /******** end 上报过滤 end ********/

  // 9. 判断文件大小(由于这么写只能触发一次,且限制条数就足够了)
  // if (!g.isSizeMax) {
  //   getStat(saveFilePath!).then((stat: any) => {
  //     // 服务器pm2 配置,分配给 nuxt 内存700M大小,这里尽量避免超过 50M (50M已经能存很多了)
  //     if (stat.size > 0) {
  //       g.isSizeMax = stat.size / 1024 / 1024 + 1 > 50;
  //     }
  //   });
  // }

  // 存在
  if (isHas) {
    // 读取现有的 JSON 文件
    const jsonString = fs.readFileSync(saveFilePath!, "utf8");
    const fileData = JSON.parse(jsonString);
    // 9.1 防止数据过大 上限 logMax 条 || g.isSizeMax
    if (fileData.list.length > logMax) {
      fileData.list.shift();
    }
    // 9.2 是否删除之前的记录,只保留最新的 xx 条
    if (body.removeLog === true) {
      if (body.num && typeof body.num === "number") {
        if (fileData.list.length > body.num) {
          fileData.list.splice(0, fileData.list.length - body.num); // 传入 0 代表全部删除
          // 将更新后的对象写回文件
          try {
            const newJsonString = JSON.stringify(fileData, null, 2);
            fs.writeFileSync(saveFilePath!, newJsonString, "utf8");
            return success("删除成功");
          } catch (error) {
            return fail({ msg: "删除成功", error });
          }
        } else {
          return fail(`数据长度不足${body.num}条,删除失败`);
        }
      }
    }

    // 9.3 插入数据
    if (body.authInfo) {
      fileData.list.push({
        time: formatDate(new Date()),
        ...body,
      });
      // 9.3.1 将 24 小时内的异常信息进行teams上报
      let errors: any = 0;
      if (!fileData.noticSuccessTime && new Date().getHours() >= 8) {
        const now = new Date();
        // 设置当前日期的时间为早上8点半, 避免时间差越来越大
        now.setHours(8, 30, 0, 0); // 时, 分, 秒, 毫秒
        fileData.noticSuccessTime = now.getTime();
        const bdtime = now.getTime() - 24 * 60 * 60 * 1000;
        fileData.list.forEach((element: any) => {
          if (element.time) {
            if (new Date(element.time).getTime() > bdtime) {
              errors += 1;
            }
          }
        });
        // 发送消息
        if (body.deviceInfo.env) {
          const qz =
            body.deviceInfo.env == "test"
              ? "test-"
              : body.deviceInfo.env == "prep"
              ? "pre-"
              : "";
          let text = `BDC-h5项目(bdc-earlyimport):${
            body.deviceInfo.env || ""
          }环境,24小时内记录异常${errors}条,请点击预览: https://${qz}bdc.btcdana.org/fx/log/errorlog?who=zhj`;
          if (body.deviceInfo.env !== "dev") {
            try {
              await sendTeamsMsg({
                url: "https://open.larksuite.com/open-apis/bot/v2/hook/80e3ea40-7807-445f-b9e2-10e2f3e07f80",
                body: {
                  msg_type: "text",
                  content: {
                    text,
                  },
                },
                // url: "https://bot.okmax.vip/api/notify_messages",
                // body: {
                //   secret: "pw#QHHPx!sk7nzX4",
                //   text,
                //   bot_id: "28:0020fede-30a5-47bc-b88c-53b6e40d54e5",
                //   bot_name: "ops_aod_bot", // 名字:改这里不生效
                //   conversation_id:
                //     "19:bab5666d53e54c269576c05d2ea2d2d0@thread.v2",
                //   service_url: "https://smba.trafficmanager.net/emea/",
                // },
              });
            } catch (error: any) {
              errors = error.message;
            }
          }
        }
      } else if (fileData.noticSuccessTime) {
        if (Date.now() - fileData.noticSuccessTime > 24 * 60 * 60 * 1000) {
          fileData.noticSuccessTime = null;
        }
      }

      // 9.3.2 将更新后的对象写回文件
      try {
        // 1. json 格式化
        const newJsonString = JSON.stringify(fileData, null, 2);
        // 2. 加锁
        const release: any = await lockfile.lock(saveFilePath);
        // 3. 保存
        fs.writeFileSync(saveFilePath!, newJsonString, "utf8");
        // 4. 释放锁
        release();
        return success({
          errors,
        });
      } catch (error: any) {
        return fail(error.message);
      }
    } else {
      return success({ msg: "插入内容格式不正确", body });
    }
  }
  // 不存在
  else {
    console.log("不存在此-目录");
    const isCreate = createDirectorySync(writePath);
    if (isCreate) {
      const writeDate = {
        create: formatDate(new Date()),
        noticSuccessTime: null,
        list: [
          {
            time: formatDate(new Date()),
            ...body,
          },
        ],
      };
      const isOK = await creatContentToPathSync(
        saveFilePath!,
        JSON.stringify(writeDate, null, 2)
      );
      if (isOK === true) {
        return success();
      } else {
        return fail(isOK);
      }
    }
  }
});
